package com.rock.securityresearch.statistic

import cats.data.NonEmptyList

case class Stastistic(datas: NonEmptyList[Double]) {
    val avg: Double = datas.foldLeft(0d)((acc, e) => acc + e) / datas.size
    val min: Double = datas.toList.min
    val max: Double = datas.toList.max

    /**
     * 中位数
     */
    val median: Double = {
        val allData = datas.toList.sorted
        val mid = allData.size / 2
        if(allData.size % 2 == 0) {
            (allData(mid) + allData(mid - 1)) / 2
        } else {
            allData(mid)
        }
    }

    /**
     * 众数, 一组数据可能有多个众数
     */
    val mode: List[Double] = {
        val map = scala.collection.mutable.Map.empty[String, Int]
        for{
            e <- datas
        } yield {
            val key = e.toString
            if(map.contains(key)) {
                map += key -> (map(key) + 1)
            } else {
                map += key -> 1
            }
            ()
        }
        val sortedList = map.toList.sortBy((k, v) => v).reverse
        findMode(sortedList)
    }

    private def findMode(datas: List[(String, Int)]): List[Double] = {
        val first = datas.head._2
        datas.filter(e => e._2 == first).map(e => e._1.toDouble)
    }
}
object Stastistic {
    def fromListUnsafe(datas: List[Double]) = Stastistic(NonEmptyList(datas.head, datas.tail))
}